/* 
  实现一个bind函数
  1 返回一个新的函数，并且可以设置参数
  2 可以当做new使用，创建对象
*/
Function.prototype.myBind = function (context) {
  console.log(this);
  if (typeof this !== 'function') {
    throw new Error('');
  }
  const self = this;

  // 参数收集
  const args = Array.prototype.slice.call(arguments, 1);
  // 创建一个临时函数，防止直接修改原型
  const Fn = function () {};
  // 返回新函数
  const func = function () {
    const newArgs = Array.prototype.slice.call(arguments);
    // 处理this
    return self.apply(this instanceof Fn ? this : context, args.concat(newArgs));
  };
  Fn.prototype = self.prototype;
  func.prototype = new Fn();
  return func;
};

function createObject(func) {
  const res = {};
  if (func.prototype !== null) {
    // 将实例的原型指向构造函数的原型
    res.__proto__ = func.prototype;
  }
  // ret为构造函数执行的结果，这里通过apply，将构造函数内部的this指向修改为指向res，即为实例对象
  const ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
  // 当我们在构造函数中明确指定了返回对象时，那么new的执行结果就是该返回对象
  if ((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
    return ret;
  }
  // 如果没有明确指定返回对象，则默认返回res，这个res就是实例对象
  return res;
}

const Func = function (name, age) {
  this.name = name;
  this.age = age;
};

// console.log(typeof Func);
const NewFunc = Func.myBind({}, 'zhangsan');
console.log(new NewFunc(11));
